import asyncio
import json
import threading

from sqlalchemy.orm import sessionmaker

from QualityInspectionViolation.DbInit.mysqlDb import session, engine
from QualityInspectionViolation.Model.Adviser import Adviser
from QualityInspectionViolation.Model.Appeal import Appeal
from QualityInspectionViolation.Model.Customer import Customer
from QualityInspectionViolation.Model.Department import Department
from QualityInspectionViolation.Model.Menu import Menu
from QualityInspectionViolation.Model.MenuSynchronization import MenuSynchronization
from QualityInspectionViolation.Model.RoleMenu import RoleMenu
from QualityInspectionViolation.Model.SecondShareRecording import SecondShareRecording
from QualityInspectionViolation.Model.ShareRecording import ShareRecording
from QualityInspectionViolation.Model.SoundRecording import SoundRecording
from QualityInspectionViolation.Model.StayRoleSynchronization import StayRoleSynchronization
from QualityInspectionViolation.Model.ViolationRecord import ViolationRecord


def insertAppealService(violationRecordId, customerId, customerName, adviserId, adviserName):

    try:
        Appeal().insertAppeal(violationRecordId, customerId, customerName, adviserId, adviserName, session)
        ViolationRecord().updateViolationRecord(violationRecordId, session)

        session.commit()
    except:
        session.rollback()

    return {"code": 200, "data": None, "message": "申诉成功"}

def reviewAppeal(appealId, pn):

    try:

        appeal = Appeal().queryAppeal(appealId, session)

        if pn == "1":

            Appeal().updateAppeal(appealId, 2, session)
            if ViolationRecord().queryViolationRecordCountByAdviser(appeal.customerId, appeal.violationRecordId, session) == 0 and Appeal().queryAppealCountByAdviser(appeal.customerId, appeal.id, session) == 0:
                Customer().updateCustomer(appeal.customerId, session)
        else:
            Appeal().updateAppeal(appealId, 3, session)

        session.commit()

    except:
        session.rollback()

    return {"code": 200, "data": None, "message": "审核成功"}

def queryMenu(adviserId):

    menuList = Menu().queryMenuByAdviser(adviserId)

    adviserMenuList = []
    for m in menuList:
        menu = {}
        menu["id"] = m.id
        menu["type"] = m.type
        menu["name"] = m.name
        menu["createdAt"] = m.createdAt.strftime("%Y-%m-%d %H:%M:%S")
        menu["updatedAt"] = m.updatedAt.strftime("%Y-%m-%d %H:%M:%S")
        adviserMenuList.append(menu)

    return adviserMenuList

def callOut(adviserId):

    roleMenu = RoleMenu().queryRoleMenu(adviserId)

    if roleMenu == None:
        return {"code": 400, "data": None, "message": "无权限"}
    else:
        return {"code": 200, "data": None, "message": "呼出成功"}

def share(soundRecordingIdList, organList, groupList, adviserList):

    try:
        sr = ShareRecording()

        for organ in organList.split(","):
            o = organ.split("*")
            shareRecording = ShareRecording()
            shareRecording.soundRecordingIdList = soundRecordingIdList
            shareRecording.type = 1
            shareRecording.shareWithId = o[0]
            shareRecording.shareWithName = o[1]
            sr.insertShareRecording(shareRecording, session)

        for group in groupList.split(","):
            g = group.split("*")
            shareRecording = ShareRecording()
            shareRecording.soundRecordingIdList = soundRecordingIdList
            shareRecording.type = 2
            shareRecording.shareWithId = g[0]
            shareRecording.shareWithName = g[1]
            sr.insertShareRecording(shareRecording, session)

        for adviser in adviserList.split(","):
            a = adviser.split("*")
            shareRecording = ShareRecording()
            shareRecording.soundRecordingIdList = soundRecordingIdList
            shareRecording.type = 3
            shareRecording.shareWithId = a[0]
            shareRecording.shareWithName = a[1]
            sr.insertShareRecording(shareRecording, session)

        session.commit()

    except:
        session.rollback()

    return {"code": 200, "data": None, "message": "分享成功"}

def secondShare(shareRecordingIdList):

    try:

        sr = ShareRecording()
        sor = SoundRecording()
        ssr = SecondShareRecording()
        a = Adviser()

        for shareRecordingId in shareRecordingIdList.split(","):

            shareRecording = sr.queryShareRecording(shareRecordingId, session)

            for soundRecordingId in shareRecording.soundRecordingIdList.split(","):
                soundRecording = sor.querySoundRecording(soundRecordingId, session)

                if shareRecording.type == 1:
                    for adviser in a.queryAdviserByOrganId(shareRecording.shareWithId, session):
                        secondShareRecording = SecondShareRecording()
                        secondShareRecording.shareRecordingId = shareRecording.id
                        secondShareRecording.recordingAddress = soundRecording.recordingAddress
                        secondShareRecording.adviserId = adviser.id
                        secondShareRecording.adviserName = adviser.name
                        ssr.insertSecondShareRecording(secondShareRecording, session)

                elif shareRecording.type == 2:
                    for adviser in a.queryAdviserByGroupId(shareRecording.shareWithId, session):
                        secondShareRecording = SecondShareRecording()
                        secondShareRecording.shareRecordingId = shareRecording.id
                        secondShareRecording.recordingAddress = soundRecording.recordingAddress
                        secondShareRecording.adviserId = adviser.id
                        secondShareRecording.adviserName = adviser.name
                        ssr.insertSecondShareRecording(secondShareRecording, session)
                else:
                    secondShareRecording = SecondShareRecording()
                    secondShareRecording.shareRecordingId = shareRecording.id
                    secondShareRecording.recordingAddress = soundRecording.recordingAddress
                    secondShareRecording.adviserId = shareRecording.shareWithId
                    secondShareRecording.adviserName = shareRecording.shareWithName
                    ssr.insertSecondShareRecording(secondShareRecording, session)

        session.commit()

    except:

        raise
        session.rollback()

    return {"code": 200, "data": None, "message": "二次分享成功"}

def putSubRoleMenu(roleId, menuList, rm, session):

    if menuList != None:
        for menu in menuList:
            resRm = rm.queryRoleMenuByRoleId(roleId, menu["id"], session)
            if menu["thisRoleMenu"] == True:
                if resRm == None:
                    roleMenu = RoleMenu()
                    roleMenu.roleId = roleId
                    roleMenu.menuId = menu["id"]
                    rm.insertRoleMenu(roleMenu, session)
            else:
                if resRm != None:
                    rm.deleteRoleMenu(resRm.id, session)

            putSubRoleMenu(roleId, menu["submenuList"], rm, session)


def roleSynchronization(stayRoleSynchronizationIdList):

    try:

        rm = RoleMenu()

        for stayRoleSynchronizationId in stayRoleSynchronizationIdList.split(","):
            stayRoleSynchronization = StayRoleSynchronization().queryStayRoleSynchronization(stayRoleSynchronizationId, session)

            role = json.loads(stayRoleSynchronization.roleInfo)
            menuList = json.loads(stayRoleSynchronization.menuInfo)

            putSubRoleMenu(role["id"], menuList, rm, session)

        session.commit()

    except:
        session.rollback()
        raise

    return {"code": 200, "data": None, "message": "菜单同步成功"}

def putSubRoleMenuThread(id_list, rm, m, session):

    try:
        for stayRoleSynchronizationId in id_list:
            stayRoleSynchronization = StayRoleSynchronization().queryStayRoleSynchronization(stayRoleSynchronizationId, session)

            role = json.loads(stayRoleSynchronization.roleInfo)
            menuList = json.loads(stayRoleSynchronization.menuInfo)

            putSubRoleMenu(role["id"], menuList, rm, session)

    except:
        m["c"] = True

def roleSynchronizationAsync(stayRoleSynchronizationIdList):

    print("async 同步")

    rm = RoleMenu()

    task_list = []

    session_list = []

    m = {
        "c" : False
    }

    id_list = stayRoleSynchronizationIdList.split(",")
    for i in range(0, 2):
        v = i

        sessionAsync = sessionmaker(bind=engine)()
        session_list.append(sessionAsync)

        t = threading.Thread(target=putSubRoleMenuThread, args=(id_list[v*1:(v+1)], rm, m, sessionAsync,))
        t.start()

        task_list.append(t)

    for k in task_list:
        k.join()

    if m["c"]:
        for s in session_list:
            s.rollback()

        return {"code": 400, "data": None, "message": "菜单同步失败"}

    else:
        for s in session_list:
            s.commit()

    return {"code": 200, "data": None, "message": "菜单同步成功"}

def putSubMenu(systemId, menuList, m, session):

    try:
        if menuList != None:
            for menu in menuList:
                newMenu = Menu()
                newMenu.systemId = systemId
                newMenu.parentMenuId = int(menu["parentMenuId"])
                # newMenu.type = int(menu["type"])
                newMenu.name = menu["name"]

                m.insertMenu(newMenu, session)

                putSubMenu(systemId, menu["submenuList"], m, session)
    except:
        session.rollback()
        raise

def menuSynchronization(menuSynchronizationIdList):

    try:

        m = Menu()

        for menuSynchronizationId in menuSynchronizationIdList.split(","):
            menuSynchronization = MenuSynchronization().queryMenuSynchronization(menuSynchronizationId, session)

            menuList = json.loads(menuSynchronization.menuInfo)
            print("menuList：", menuList)

            m.deleteMenu(menuSynchronization.systemId, session)

            putSubMenu(menuSynchronization.systemId, menuList, m, session)

        session.commit()

    except:
        session.rollback()
        raise

    return {"code": 200, "data": None, "message": "菜单同步成功"}

def queryDepartmentAdviser(organId, dimension, position, pageSize, pageNo):

    try:
        dt = Department()
        ar = Adviser()

        infoList = []
        if len(organId) == 4:
            if dimension == "1":
                for dept in dt.queryDepartment(organId, len(organId), int(pageSize), int(pageNo), session):
                    info = {
                        "id" : dept.organId,
                        "name" : dept.name,
                        "type" : 1,
                    }
                    infoList.append(info)

                return infoList

            elif dimension == "2":
                for dept in dt.queryDepartment(organId, len(organId)+2, int(pageSize), int(pageNo), session):
                    info = {
                        "id": dept.organId,
                        "name": dept.name,
                        "type": 1,
                    }
                    infoList.append(info)

                return infoList

            elif dimension == "3":
                for dept in dt.queryDepartment(organId, len(organId)+4, int(pageSize), int(pageNo), session):
                    info = {
                        "id": dept.organId,
                        "name": dept.name,
                        "type": 1,
                    }
                    infoList.append(info)

                return infoList

            elif dimension == "4":
                for adv in ar.queryGroupLeaderAdvise(organId, len(organId)+6, int(pageSize), int(pageNo), session):

                    print()

                    info = {
                        "id" : adv.groupId,
                        "name" : adv.name+"小组",
                        "type": 2,
                    }
                    infoList.append(info)

                return infoList

            elif dimension == "5":
                if position == "1":
                    for adv in ar.queryGroupAdvise(organId, len(organId)+6, int(pageSize), int(pageNo), session):
                        info = {
                            "id": adv.id,
                            "name": adv.name,
                            "type": 3,
                        }
                        infoList.append(info)

                    return infoList

                elif position == "2":
                    for adv in ar.queryNoGroupAdvise(organId, len(organId)+6, int(pageSize), int(pageNo), session):
                        info = {
                            "id": adv.id,
                            "name": adv.name,
                            "type": 3,
                        }
                        infoList.append(info)

                    return infoList

                else:
                    for adv in ar.queryAdvise(organId, len(organId)+6, int(pageSize), int(pageNo), session):
                        info = {
                            "id": adv.id,
                            "name": adv.name,
                            "type": 3,
                        }
                        infoList.append(info)

                    return infoList

        elif len(organId) == 6:
            if dimension == "2":
                for dept in dt.queryDepartment(organId, len(organId), int(pageSize), int(pageNo), session):
                    info = {
                        "id": dept.organId,
                        "name": dept.name,
                        "type": 1,
                    }
                    infoList.append(info)

                return infoList

            elif dimension == "3":
                for dept in dt.queryDepartment(organId, len(organId)+2, int(pageSize), int(pageNo), session):
                    info = {
                        "id": dept.organId,
                        "name": dept.name,
                        "type": 1,
                    }
                    infoList.append(info)

                return infoList

            elif dimension == "4":
                adviserList = []
                for adv in ar.queryGroupAdvise(organId, len(organId)+4, int(pageSize), int(pageNo), session):
                    info = {
                        "id": adv.groupId,
                        "name": adv.name + "小组",
                        "type": 2,
                    }
                    infoList.append(info)

                return infoList

            elif dimension == "5":
                adviserList = []
                if position == "1":
                    for adv in ar.queryGroupAdvise(organId, len(organId)+4, int(pageSize), int(pageNo), session):
                        info = {
                            "id": adv.id,
                            "name": adv.name,
                            "type": 3,
                        }
                        infoList.append(info)

                    return infoList

                elif position == "2":
                    for adv in ar.queryNoGroupAdvise(organId, len(organId)+4, int(pageSize), int(pageNo), session):
                        info = {
                            "id": adv.id,
                            "name": adv.name,
                            "type": 3,
                        }
                        infoList.append(info)

                    return infoList

                else:
                    for adv in ar.queryAdvise(organId, len(organId)+4, int(pageSize), int(pageNo), session):
                        info = {
                            "id": adv.id,
                            "name": adv.name,
                            "type": 3,
                        }
                        infoList.append(info)

                    return infoList

        elif len(organId) == 8:
            if dimension == "3":
                for dept in dt.queryDepartment(organId, len(organId), int(pageSize), int(pageNo), session):
                    info = {
                        "id": dept.organId,
                        "name": dept.name,
                        "type": 1,
                    }
                    infoList.append(info)

                return infoList

            elif dimension == "4":
                for adv in ar.queryGroupAdvise(organId, len(organId)+2, int(pageSize), int(pageNo), session):
                    info = {
                        "id": adv.groupId,
                        "name": adv.name + "小组",
                        "type": 2,
                    }
                    infoList.append(info)

                return infoList

            elif dimension == "5":
                if position == "1":
                    for adv in ar.queryGroupAdvise(organId, len(organId)+2, int(pageSize), int(pageNo), session):
                        info = {
                            "id": adv.id,
                            "name": adv.name,
                            "type": 3,
                        }
                        infoList.append(info)

                    return infoList

                elif position == "2":
                    for adv in ar.queryNoGroupAdvise(organId, len(organId)+2, int(pageSize), int(pageNo), session):
                        info = {
                            "id": adv.id,
                            "name": adv.name,
                            "type": 3,
                        }
                        infoList.append(info)

                    return infoList

                else:
                    for adv in ar.queryAdvise(organId, len(organId)+2, int(pageSize), int(pageNo), session):
                        info = {
                            "id": adv.id,
                            "name": adv.name,
                            "type": 3,
                        }
                        infoList.append(info)

                    return infoList
        session.commit()

    except:
        session.rollback()
        raise

async def putSubRoleMenuAsync(id_list, rm, m, session):
    try:
        for stayRoleSynchronizationId in id_list:
            stayRoleSynchronization = StayRoleSynchronization().queryStayRoleSynchronization(stayRoleSynchronizationId,
                                                                                             session)

            role = json.loads(stayRoleSynchronization.roleInfo)
            menuList = json.loads(stayRoleSynchronization.menuInfo)

            putSubRoleMenu(role["id"], menuList, rm, session)

    except:
        m["c"] = True

async def roleSynchronizationAsyncio(stayRoleSynchronizationIdList):
    print("async 同步")

    rm = RoleMenu()

    task_list = []

    session_list = []

    m = {
        "c": False
    }

    id_list = stayRoleSynchronizationIdList.split(",")
    for i in range(0, 2):
        v = i

        sessionAsync = sessionmaker(bind=engine)()
        session_list.append(sessionAsync)

        task_list.append(asyncio.create_task(putSubRoleMenuAsync(id_list[v * 1:(v + 1) * 1], rm, m, sessionAsync)))

    await asyncio.wait(task_list)

    if m["c"]:
        for s in session_list:
            s.rollback()

        return {"code": 400, "data": None, "message": "菜单同步失败"}

    else:
        for s in session_list:
            s.commit()

    # lock = asyncio.Lock()
    #
    # await lock.acquire()
    # await lock.release()

    return {"code": 200, "data": None, "message": "菜单同步成功"}

def start(stayRoleSynchronizationIdList):
    asyncio.run(roleSynchronizationAsyncio(stayRoleSynchronizationIdList))













































